﻿// HSS.Interlink.Stopwatch.cs
// ----------------------------------------------------------------------------
// Licensed under the MIT license (http://www.opensource.org/licenses/mit-license.html)
// ----------------------------------------------------------------------------
// HighSpeed-Solutions, LLC
// Copyright (c) 2001-2010
// ----------------------------------------------------------------------------
// File:       Stopwatch.cs
// Author:     HSS\gbanta
// Created:    07/16/2011
// Modified:   07/22/2011
// ----------------------------------------------------------------------------
namespace HSS.Interlink
{
	#region Using Directives
	using System;
	#endregion

	#region Stopwatch
	/// <summary>
	/// Stopwatch is used to measure the general performance of Silverlight 
	/// functionality. The resolution of this timer is limited to <see cref="Environment.TickCount"/>.
	/// </summary>
	internal sealed class Stopwatch
	{
		#region Fields
		private int startTickCount = 0;
		private int endTickCount = 0;
		#endregion

		#region Constructors
		/// <summary>
		/// Creates an instance of the Stopwatch class.
		/// </summary>
		public Stopwatch()
		{
		}
		#endregion

		#region Properties
		/// <summary>
		/// Gets a value indicating whether the instance is currently recording.
		/// </summary>
		public bool IsRunning { get; private set; }
		/// <summary>
		/// Gets the Elapsed time as the total number of milliseconds.
		/// </summary>
		public long ElapsedMilliseconds
		{
			get
			{
				return this.ElapsedTicks / TimeSpan.TicksPerMillisecond;
			}
		}
		/// <summary>
		/// Gets the number of ticks.
		/// </summary>
		public long ElapsedTicks
		{
			get
			{
				return this.Elapsed.Ticks;
			}
		}
		/// <summary>
		/// Gets the Elapsed time as a Timespan.
		/// </summary>
		public TimeSpan Elapsed
		{
			get
			{
				if (startTickCount == 0)
					return TimeSpan.Zero;
				if (endTickCount == 0)
					return TimeSpan.FromMilliseconds(Environment.TickCount - startTickCount);
				return TimeSpan.FromMilliseconds(endTickCount - startTickCount);
			}
		}
		#endregion

		#region Methods

		/// <summary>
		/// Creates a new instance of the class and starts the watch immediately.
		/// </summary>
		/// <returns>An instance of Stopwatch, running.</returns>
		public static Stopwatch StartNew()
		{
			Stopwatch sw = new Stopwatch();
			sw.Start();
			return sw;
		}

		/// <summary>
		/// Completely resets and deactivates the timer.
		/// </summary>
		public void Reset()
		{
			startTickCount = 0;
			endTickCount = 0;
			IsRunning = false;
		}
		/// <summary>
		/// Begins the timer.
		/// </summary>
		public void Start()
		{
			if (this.IsRunning)
				return;
			this.IsRunning = true;

			if (this.startTickCount > 0 && this.endTickCount > 0)
				this.startTickCount = this.startTickCount + (Environment.TickCount - this.endTickCount);
			else
				this.startTickCount = Environment.TickCount;
		}
		/// <summary>
		/// Stops the current timer.
		/// </summary>
		public void Stop()
		{
			if (this.IsRunning)
			{
				endTickCount = Environment.TickCount;
				this.IsRunning = false;
			}
		}
		#endregion
	}
	#endregion
}